<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Leaflet</title>
    <link rel="stylesheet" href="leaflet.css" />
    <script src="leaflet.js"></script>
    <script src="plugins/leaflet-ant-path.js"></script>
    <script src="plugins/leaflet.rotatedMarker.js"></script>
    <!--计算点位方向-->
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        height: 100%;
      }

      #map {
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>

    <script>
      class AntPathPolyline {
        static polylineStyleConfig = [
          {
            color: "#006600",
            fillColor: "#006600",
            pulseColor: "#e5ffe5"
          },
          {
            color: "#0000cc",
            fillColor: "#0000cc",
            pulseColor: "#ccccff"
          },
          {
            color: "#e62f00",
            fillColor: "#e62f00",
            pulseColor: "#ffc2b3"
          },
          {
            color: "#8600b3",
            fillColor: "#8600b3",
            pulseColor: "#ecb3ff"
          },
          {
            color: "#b35900",
            fillColor: "#b35900",
            pulseColor: "#ffd9b3"
          },
          {
            color: "#ff9900",
            fillColor: "#ff9900",
            pulseColor: "#ffe0b3"
          },
          {
            color: "#00b2b3",
            fillColor: "#00b2b3",
            pulseColor: "#b3ffff"
          },
          {
            color: "#000000",
            fillColor: "#000000",
            pulseColor: "#FFFFFF"
          },
          {
            color: "#006699",
            fillColor: "#006699",
            pulseColor: "#b3e6ff"
          },
          {
            color: "#cc0099",
            fillColor: "#cc0099",
            pulseColor: "#ffb3ec"
          }
        ];

        static iconConfig = [
          "./icons/car0.png",
          "./icons/car1.png",
          "./icons/car2.png",
          "./icons/car3.png",
          "./icons/car4.png",
          "./icons/car5.png",
          "./icons/car6.png",
          "./icons/car7.png",
          "./icons/car8.png",
          "./icons/car9.png"
        ];

        static layerGroups = {};

        static calculateBearing(lat1, lon1, lat2, lon2) {
          const dLon = (lon2 - lon1) * (Math.PI / 180);
          const y = Math.sin(dLon) * Math.cos(lat2 * (Math.PI / 180));
          const x =
            Math.cos(lat1 * (Math.PI / 180)) *
              Math.sin(lat2 * (Math.PI / 180)) -
            Math.sin(lat1 * (Math.PI / 180)) *
              Math.cos(lat2 * (Math.PI / 180)) *
              Math.cos(dLon);
          let bearing = Math.atan2(y, x) * (180 / Math.PI);

          // 将方位角规范化为0到360度之间
          if (bearing < 0) {
            bearing = (bearing + 360) % 360;
          }

          return bearing;
        }

        drawPolyline(
          map,
          points,
          width,
          polylineStyleConfig,
          iconConfig,
          layerGroupName
        ) {
          if (points.length === 0) {
            return;
          }

          if (AntPathPolyline.layerGroups[layerGroupName]) {
            map.removeLayer(AntPathPolyline.layerGroups[layerGroupName]);
            AntPathPolyline.layerGroups[layerGroupName] = L.layerGroup().addTo(
              map
            );
          } else {
            AntPathPolyline.layerGroups[layerGroupName] = L.layerGroup().addTo(
              map
            );
          }

          // 起始点
          const marker = L.marker(points[0], {
            icon: L.icon({
              iconUrl: "./icons/nav.svg", // 图标图片的URL
              iconSize: [32, 32], // 图标的大小
              iconAnchor: [15, 15], // 图标的锚点，即图标的位置应该放置在地图上的位置
              popupAnchor: [-3, -76] // 弹出框的锚点，即当你点击图标时，弹出框应该出现在哪个位置
            })
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 线
          L.polyline
            .antPath(points, {
              ...polylineStyleConfig,
              opacity: 6,
              delay: 10000,
              dashArray: [5, 30]
            })
            .addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 最新的点
          L.marker(points[points.length - 1], {
            icon: L.icon({
              iconUrl: iconConfig,
              iconSize: [30, 30], // icon的大小
              iconAnchor: [16, 15], // icon的渲染的位置（相对与marker）
              shadowAnchor: [0, 0], // shadow的渲染的位置（相对于marker）
              popupAnchor: [0, 0] //若是绑定了popup的popup的打开位置（相对于icon）
            }),
            title: "test",
            draggable: true,
            rotationAngle:
              points.length > 1
                ? AntPathPolyline.calculateBearing(
                    points[points.length - 2][0],
                    points[points.length - 2][1],
                    points[points.length - 1][0],
                    points[points.length - 1][1]
                  )
                : 0
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          const circle = L.circle(points[points.length - 1], {
            stroke: true,
            dashArray: "4",
            color: "red",
            fillColor: "#f03",
            fillOpacity: 0.2,
            weight: 2,
            radius: 1200 * width
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          circle.on("mouseover", e => {
            alert("半径为0.5km.");
          });
        }
      }

      const map = L.map("map").setView([28.23, 112.93], 13);

      L.tileLayer(
        "http://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
        {
          minZoom: 11,
          maxZoom: 16
          // attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }
      ).addTo(map);

      const test1 = new AntPathPolyline();
      const test2 = new AntPathPolyline();
      const test3 = new AntPathPolyline();
      const test4 = new AntPathPolyline();
      const test5 = new AntPathPolyline();
      const test6 = new AntPathPolyline();
      const test7 = new AntPathPolyline();
      const test8 = new AntPathPolyline();
      const test9 = new AntPathPolyline();
      const test10 = new AntPathPolyline();

      let width = 0.25;

      const points1 = [];
      const points2 = [];
      const points3 = [];
      const points4 = [];
      const points5 = [];
      const points6 = [];
      const points7 = [];
      const points8 = [];
      const points9 = [];
      const points10 = [];
      
      setInterval(function() {
        points1.push([28.23 + Math.random() / 20, 112.93 + Math.random() / 20]);
        test1.drawPolyline(
          map,
          points1,
          width,
          AntPathPolyline.polylineStyleConfig[0],
          AntPathPolyline.iconConfig[0],
          "line1"
        );
      }, 1000);

      // setInterval(function() {
      //   points2.push([28.23 + Math.random() / 21, 112.93 + Math.random() / 21]);
      //   test2.drawPolyline(
      //     map,
      //     points2,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[1],
      //     AntPathPolyline.iconConfig[1],
      //     "line2"
      //   );
      // }, 2000);

      // setInterval(function() {
      //   points3.push([28.23 + Math.random() / 22, 112.93 + Math.random() / 22]);
      //   test3.drawPolyline(
      //     map,
      //     points3,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[2],
      //     AntPathPolyline.iconConfig[2],
      //     "line3"
      //   );
      // }, 3000);

      // setInterval(function() {
      //   points4.push([28.23 + Math.random() / 23, 112.93 + Math.random() / 23]);
      //   test4.drawPolyline(
      //     map,
      //     points4,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[3],
      //     AntPathPolyline.iconConfig[3],
      //     "line4"
      //   );
      // }, 4000);

      // setInterval(function() {
      //   points5.push([28.23 + Math.random() / 24, 112.93 + Math.random() / 24]);
      //   test5.drawPolyline(
      //     map,
      //     points5,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[4],
      //     AntPathPolyline.iconConfig[4],
      //     "line5"
      //   );
      // }, 5000);

      // setInterval(function() {
      //   points6.push([28.23 + Math.random() / 25, 112.93 + Math.random() / 25]);
      //   test6.drawPolyline(
      //     map,
      //     points6,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[5],
      //     AntPathPolyline.iconConfig[5],
      //     "line6"
      //   );
      // }, 6000);

      // setInterval(function() {
      //   points7.push([28.23 + Math.random() / 26, 112.93 + Math.random() / 26]);
      //   test7.drawPolyline(
      //     map,
      //     points7,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[6],
      //     AntPathPolyline.iconConfig[6],
      //     "line7"
      //   );
      // }, 7000);

      // setInterval(function() {
      //   points8.push([28.23 + Math.random() / 27, 112.93 + Math.random() / 27]);
      //   test8.drawPolyline(
      //     map,
      //     points8,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[7],
      //     AntPathPolyline.iconConfig[7],
      //     "line8"
      //   );
      // }, 8000);

      // setInterval(function() {
      //   points9.push([28.23 + Math.random() / 28, 112.93 + Math.random() / 28]);
      //   test9.drawPolyline(
      //     map,
      //     points9,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[8],
      //     AntPathPolyline.iconConfig[8],
      //     "line9"
      //   );
      // }, 9000);

      // setInterval(function() {
      //   points10.push([28.23 + Math.random() / 29, 112.93 + Math.random() / 29]);
      //   test10.drawPolyline(
      //     map,
      //     points10,
      //     width,
      //     AntPathPolyline.polylineStyleConfig[9],
      //     AntPathPolyline.iconConfig[9],
      //     "line10"
      //   );
      // }, 10000);
    </script>
  </body>
</html>
